from os.path import join
from csv import reader as csv_reader
from matlab.engine import start_matlab, MatlabEngine

from src.consumer.mimo import MimoAdaptor
from src.logger import Logger
from src.processor.mimo_decode import DecodeBitStream


class MatlabAdaptor(MimoAdaptor):
    def __init__(self, lib_path: str, assets_dir: str) -> None:
        self.assets_dir = assets_dir

        matlabEngine = start_matlab()
        if isinstance(matlabEngine, MatlabEngine):
            Logger.Info("matlab engine start success")
            matlabEngine.cd(lib_path, nargout=0)
            self.matlab = matlabEngine
        else:
            Logger.Error("matlab engine start failed")
            exit(1)

    def mimo_decode(self, processor):
        """
        ### MIMO信道模型
        - `number_of_receive_antennas`: 接收天线数
        - `modulationMode`: 调制方式 `1 - 3`
        - `bit_stream`: 4 比特流 0 | 1
        - `noise_rate`: 噪声比 `0 - 30`
        - `is_random`: 是否随机填充比特流
        """
        return DecodeBitStream(
            int(x)
            for x in self.matlab.mimo_decode(
                processor.number_of_receive_antennas,
                processor.modulationMode,
                processor.noise_rate,
                processor.bit_stream[0],
                processor.bit_stream[1],
                processor.bit_stream[2],
                processor.bit_stream[3],
                0,
            )[0]  # type: ignore
        )

    MimoChartPoints = tuple[list[int], list[float]]

    def mimo_plot(self, processor):
        """
        ### MIMO信道模型 - 画图
        - `number_of_receive_antennas`: 接收天线数
        - `modulationMode`: 调制方式 `1 - 3`
        - `noise_rate`: 噪声比 `0 - 30`
        - `counts`: 次数? float

        - `bit_stream`: 4 比特流 0 | 1  [legacy]
        - `is_random`: 是否随机填充比特流 [legacy]
        """
        csv_file = join(self.assets_dir, f"mimo-plot-{processor.id}.csv")
        self.matlab.mimo_plot(
            processor.number_of_receive_antennas,
            processor.modulationMode,
            processor.noise_rate,
            1,
            1,
            1,
            1,
            1,
            processor.counts,
            csv_file,
        )

        return self.mimo_plot_csv_reader(csv_file)

    def mimo_plot_csv_reader(self, csv_file: str):
        """
        `mimo_plot` 生成的 csv 文件读取 (semilogx 画图的 x, y 坐标点, 可能为复数, 但只取实部)
        """
        file = open(csv_file, "r")
        y = csv_reader(file).__next__()
        x = csv_reader(file).__next__()
        file.close()
        return [int(i) for i in x], [complex(i.replace("i", "j")).real for i in y]
